import { router } from "./index";
import type { RouteRecordRaw, RouteRecordNormalized } from "vue-router";
import Layout from "@/layout/index.vue";
import { cloneDeep } from "lodash-es";
import store from "@/store";
import { useTimeoutFn } from "@vueuse/core";

// 定义标签路由配置类型
interface tagRouteConfigs {
  path: string;
  name: string;
  meta: any;
}

// 处理静态路由
const constantRoutesFilter = (data: RouteRecordRaw[], isAsync: boolean, isMenu:boolean): RouteRecordRaw[] => {
  let newData: RouteRecordRaw[] = [];
  if(isAsync){
    // 需要的是动态路由子集的部分
    newData = routerTreeToFlattening(data.filter((item: RouteRecordRaw)=>{
      return item.meta && item.meta.pid != undefined && item.meta.pid != 0;
    }))
  }else{
    if(isMenu){
      // 作为菜单数据使用，不需要根路由Layout
      newData = data.filter((item:RouteRecordRaw)=>{
        return item.meta && item.meta.pid != undefined && item.meta.pid == 0;
      });
    }else{
      // 需要的是可直接实例化的静态路由部分
      newData.push({
        path: "/",
        name: "Layout",
        component: Layout,
        redirect: "/Home",
        children:[],
        meta:{
          sort:1,
          showLink:true,
        }
      });
      let sonData = data.filter((item: RouteRecordRaw)=>{
        return item.meta && item.meta.pid != undefined && item.meta.pid == 0;
      })
      newData[0].children = routerTreeToFlattening(routerToTree(routerTreeToFlattening(sonData)));
    }
  }
  return newData;
}

// 过滤后端传来的动态路由 重新生成规范路由，并与静态路由中归属于动态路由的子集数据进行合并
const addAsyncRoutes = (arrRoutes:any,constantNotRootRoutes:any) => {
  if (!arrRoutes || !arrRoutes.length) return;
  const modulesRoutes = import.meta.glob("/src/views/**/**.vue");
  var routerData:any = [];
  arrRoutes.forEach((v:any) => {
    var itemData = {
      path:'',
      name:'',
      redirect:'',
      component:{},
      meta:{
        id:0,
        pid:0,
        icon:'',
        title:'',
        showLink:true,
        sort:0,
        transitionName:'',
        keepAlive:false,
      }
    };
    itemData.path = v.url;
    itemData.name = v.route;
    itemData.component = modulesRoutes[`/src/views${v.url}/index.vue`];
    if (v.redirect!="") {
      itemData.redirect = v.redirect;
    }
    itemData.meta.id = v.id;
    itemData.meta.pid = v.pid;
    itemData.meta.icon = v.icon;
    itemData.meta.title = v.title;
    itemData.meta.showLink = v.showLink;
    itemData.meta.sort = v.sort;
    itemData.meta.transitionName = v.transitionName;
    itemData.meta.keepAlive = v.keepAlive;
    routerData.push(itemData);
  });
  // 合并动态获取路由与静态路由中从属于动态路由子集的数据
  let allRouterData = routerData.concat(...constantNotRootRoutes);
  console.log(allRouterData,"合并后的动态路由");
  return allRouterData;
};

// 将规范路由的一维数组转为树形结构
const routerToTree = (arrRoutes:any) => {
  var parents = arrRoutes.filter(function (item:any) {
      return item.meta.pid == 0;
  });
  var children = arrRoutes.filter(function (item:any) {
      return item.meta.pid != 0;
  });
  // 递归处理动态路由层级
  convert(parents, children);
  return parents;
}

// 递归处理动态路由层级
const convert = (parents:any,children:any) =>{
  parents.forEach(function (item:any) {
    if(!item.meta.breadcrumb){
        item.meta.breadcrumb = [];
        var itemBreadcrumb = {
            path:"",
            title:"",
            redirect:""
        };
        itemBreadcrumb.path = item.path;
        itemBreadcrumb.redirect = item.redirect!=''?item.redirect:'';
        itemBreadcrumb.title = item.meta.title as string;
        if(item.path!=='/Home'){
            item.meta.breadcrumb.push({path:"/Home",title:"首页",redirect:""});
        }
        item.meta.breadcrumb.push(itemBreadcrumb);
    }
    item.children = [];
    children.forEach(function (current:any, index:any) {
      if (current.meta.pid === item.meta.id) {
        current.meta.breadcrumb = cloneDeep(item.meta.breadcrumb);
        var childrenItemBreadcrumb = {
            path:"",
            title:"",
            redirect:""
        };
        childrenItemBreadcrumb.path = current.path;
        childrenItemBreadcrumb.title = current.meta.title as string;
        childrenItemBreadcrumb.redirect = current.redirect!=''?current.redirect:'';
        current.meta.breadcrumb.push(childrenItemBreadcrumb);
        var temp = children.filter(function(v:any,idx:any){
          return idx != index;
        }); // 删除已匹配项，这里未使用JSON.parse(JSON.stringify(children))是因为路由的component已经是函数形式，再格式化后，模块导入功能丢失，会导致找不到模块
        item.children.push(current);
        convert([current], temp); // 递归
      }
    });
  });
}

// 引入动态路由获取接口
import { getAsyncRoutes } from "@/api/routes";
// 初始化路由
const initRouter = (constantNotRootRoutes:any) => {
  return new Promise(resolve => {
    // 调用接口获取动态路由
    getAsyncRoutes().then((data:any) => {
      if (data.data.length > 0) {
        // 获取的动态路由处理成规范路由后，通过map方法，循环加入到路由实例中
        routerTreeToFlattening(routerToTree(addAsyncRoutes(data.data,constantNotRootRoutes)))?.map((v: any) => {
          if(!router.options.routes[0].children){
            router.options.routes[0].children = [];
          }
          // 防止重复添加路由
          if (router.options.routes[0].children.findIndex(value => value.path === v.path) !== -1) {
            return;
          } else {
            // 切记将路由push到routes后还需要使用addRoute，这样路由才能正常跳转
            router.options.routes[0].children.push(v);
            // 这里需要注意 addRouter中的Layout参数，是用来将路由添加到框架层路由下的，如果动态路由有非框架层路由下的，这里需要做判断
            if (!router.hasRoute(v?.name)) router.addRoute('Layout',v);
          }
          resolve(router);
        });
      }
      // 将转化为树形结构的路由数据传递给vuex去处理成菜单数据
      store.dispatch('routeMenus/getWholeRouteMenus',cloneDeep(routerToTree(addAsyncRoutes(data.data,constantNotRootRoutes))));
      console.log(router.options,"最终路由数据");
      // 404匹配规则需在最后加入到路由实例中
      router.addRoute({path: "/:pathMatch(.*)",redirect: "/Error/404"});
    });
  });
};

// 树形结构数据递归排序
export const treeToAscending = (arr:any) =>{
  var newTree = ascending(arr);
  newTree.forEach(function(item:any){
    if(item.children&&item.children.length>1){
      item.children = ascending(item.children);
    }
  });
  return newTree;
};

// 按照路由中meta下的sort等级升序来排序路由
export const ascending = (arr:any) => {
  return arr.sort((a: any, b: any) => {
      return a?.meta?.sort - b?.meta?.sort;
  });
};

// 过滤meta中showLink为false的路由
export const filterMenuTree = (data:any) => {
  const newTree = data.filter((v:any) => v.meta.showLink);
  newTree.forEach((v:any) => v.children && (v.children = filterMenuTree(v.children)));
  return newTree;
};

// 动态添加标签栏路由信息
const dynamicRouteTag = (value) => {
  console.log(value,"debug");
  if(value.name==='redirect') return;
  const hasValue = store.state.multiTags.multiTags.some(item => {
    return item.path === value.path;
  });
  let tagRoute = {
    path:'',
    name:'',
    meta:{},
  };
  console.log(hasValue,"是否找到路由");
  if(!hasValue){
    if(value.meta.realPath){
      console.log(value,"判断realPath");
      let currentMeta = value.meta;
      currentMeta.title = `No.${value.params.id} - 详情信息`;
      tagRoute.path = value.path;
      tagRoute.name = value.name;
      tagRoute.meta = currentMeta;
    }else{
      if(value.meta.name){
        console.log(value,"判断name");
        tagRoute.path = value.path;
        tagRoute.name = value.name;
        tagRoute.meta = value.meta;
      }else{
        concatPath(router.options.routes, value);
      }
    }
    if(tagRoute.path!==''){
      store.dispatch("multiTags/handleTags",{mode:"push",value:tagRoute});
    }
  }
  // 递归寻找选中的路由，并缓存到标签页信息中
  function concatPath(arr: readonly RouteRecordRaw[], value) {
    arr.forEach((arrItem: any) => {
      if (arrItem.path === value.path&&!arrItem.meta.hideTag) {
        tagRoute.path = value.path;
        tagRoute.name = arrItem.name;
        tagRoute.meta = arrItem.meta;
        console.log(tagRoute,"找到路由");
      } else {
        if (arrItem.children && arrItem.children.length > 0) {
          concatPath(arrItem.children, value);
        }
      }
    });
  }
}

// 处理缓存路由（添加、删除、刷新）
const handleAliveRoute = (matched: RouteRecordNormalized[], mode?: string) => {
  switch (mode) {
    case "add":
      matched.forEach(v => {
        store.dispatch('keepAlivePages/keepAliveOperate',{ mode: "add", name: v.name });
      });
      break;
    case "delete":
      store.dispatch('keepAlivePages/keepAliveOperate',{ mode: "delete", name: matched[matched.length - 1].name });
      break;
    default:
      store.dispatch('keepAlivePages/keepAliveOperate',{ mode: "delete", name: matched[matched.length - 1].name });
      // 这里需要设置一个比较小的时间差，时间差太长会造成缓存页面还未添加上，页面已实例化，导致onActivated生命周期不能执行
      useTimeoutFn(() => {
        matched.forEach(v => {
          store.dispatch('keepAlivePages/keepAliveOperate',{ mode: "add", name: v.name });
        });
      }, 10);
  }
};

// 批量删除缓存路由(keepalive)
const delAliveRoutes = (delAliveRouteList: Array<tagRouteConfigs>) => {
  delAliveRouteList.forEach(route => {
    store.dispatch('keepAlivePages/keepAliveOperate',{ mode: "delete", name: route?.name });
  });
};

/**
 * 将树形结构路由处理成一维数组
 * @param routesList 传入路由
 * @returns 返回处理后的一维路由
 */
const routerTreeToFlattening = (routesList: RouteRecordRaw[]) => {
  if (routesList.length === 0) return routesList;
  let newRouteList = [];
  function flatteningRoute(routesList){
    routesList.forEach(function(item){
        let newItem = cloneDeep(item);
        newItem.children = [];
        newRouteList.push(newItem);
        if(item.children&&item.children.length>0){
            flatteningRoute(item.children)
        };
    });
  }
  flatteningRoute(routesList);
  console.log(newRouteList,"拍平的路由")
  return newRouteList;
}

export {
  constantRoutesFilter,
  initRouter,
  dynamicRouteTag,
  handleAliveRoute,
  delAliveRoutes
};